package project.ia04.agents.studio.GUICommunication;

import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

import project.ia04.agents.studio.StudioAgent;
import project.ia04.utils.Data;
import project.ia04.utils.Staff;
import jade.core.AID;
import jade.core.behaviours.Behaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;

public class SendStaffListBehaviour extends Behaviour {

	private ACLMessage message;
	private int count = 0;
	private int nbStaffAgent = 0;
	private AID[] aidStaffAgent;
	private boolean begin = true;

	private final ArrayList<Staff> staffList = new ArrayList<Staff>();

	public SendStaffListBehaviour(final ACLMessage message) {
		this.message = message;
	}

	@Override
	public void action() {
		if (this.begin) {
			this.aidStaffAgent = ((StudioAgent)myAgent).getStaffAgents();
			this.nbStaffAgent = this.aidStaffAgent.length;
			for (int i = 0; i < this.nbStaffAgent; i++) {
				final ACLMessage message = new ACLMessage(
						ACLMessage.REQUEST);
				message.setConversationId(Data.GETPROP);
				message.addReceiver(this.aidStaffAgent[i]);
				this.myAgent.send(message);
			}
			this.begin = false;
		} else {
			if (this.count < this.nbStaffAgent) {
				MessageTemplate tpl = MessageTemplate.and(
						MessageTemplate
								.MatchPerformative(ACLMessage.INFORM),
						MessageTemplate.MatchConversationId(Data.GETPROP));
				ACLMessage message = this.myAgent.receive(tpl);
				if (message != null) {
					this.staffList.add(new Staff(((StudioAgent)myAgent).getFieldDeserialize(
							Data.STAFFNAME, message.getContent()),
							((StudioAgent)myAgent).getFieldDeserialize(Data.ASKCLASS,
									message.getContent()),
							getLvlDeserialize(message.getContent()),
							getStaminaDeserialize(message.getContent())));
					this.count++;
				} else {
					block();
				}
			} else {
				final ACLMessage reply = this.message.createReply();
				reply.setPerformative(ACLMessage.INFORM);
				reply.setContent(serialize());// JSON List Staff
				this.myAgent.send(reply);
				this.count++;
			}
		}
	}

	private int getStaminaDeserialize(String content) {
		int res = -1;
		final ObjectMapper mapper = new ObjectMapper();
		Map<String, Object> map;
		try {
			map = mapper.readValue(content, Map.class);
			res = (Integer) map.get(Data.STAMINA);
		} catch (final JsonParseException e) {
			e.printStackTrace();
		} catch (final JsonMappingException e) {
			e.printStackTrace();
		} catch (final IOException e) {
			e.printStackTrace();
		}
		return res;
	}

	private int getLvlDeserialize(final String content) {
		int res = -1;
		final ObjectMapper mapper = new ObjectMapper();
		Map<String, Object> map;
		try {
			map = mapper.readValue(content, Map.class);
			res = (Integer) map.get(Data.ASKLVL);
		} catch (final JsonParseException e) {
			e.printStackTrace();
		} catch (final JsonMappingException e) {
			e.printStackTrace();
		} catch (final IOException e) {
			e.printStackTrace();
		}
		return res;
	}

	private String serialize() {
		final Map<String, Object> map = new HashMap<String, Object>();
		map.put(Data.GETSTAFFSLIST, this.staffList);
		final StringWriter sw = new StringWriter();
		final ObjectMapper mapper = new ObjectMapper();
		try {
			mapper.writeValue(sw, map);
		} catch (final JsonGenerationException e) {
			e.printStackTrace();
		} catch (final JsonMappingException e) {
			e.printStackTrace();
		} catch (final IOException e) {
			e.printStackTrace();
		}
		return sw.toString();
	}

	@Override
	public boolean done() {
		return this.count == (this.nbStaffAgent + 1);
	}
}
